﻿using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = @"4:
:20:123456
:23B:CRED
:32A:140403USD1000,25
:33B:USD1000,25
:50K:/987654321
BATMAN
GOTHAM CITY
USA
:52A:SHBKKRSE
:53A:BOFAUS3N
:57D:JUSTICE LEAGUE
INDONESIA
:59:/123456789
JUNAIDI
JAKARTA
:71A:BEN
:71F:USD0,
:72:/INS/GOTHAM BANK
//REF.123 MUR.123.
//BME CHARGES USD.20.00";

            Dictionary<string, string> block4 = GetSwiftBlock4(text);
            foreach (var item in block4)
            {
                Console.WriteLine("{0} : {1}", item.Key, item.Value);
            }
            Console.WriteLine("");
            Console.ReadLine();
        }

        private static Dictionary<string, string> GetSwiftBlock4(string text)
        {
            Dictionary<string, string> block = new Dictionary<string, string>();

            text = Validate(text);
            int index1 = 0;
            if ((int)text[index1] == 52)
                ++index1;
            if ((int)text[index1] == 58)
                ++index1;
            while (index1 < text.Length)
            {
                int startIndex1 = index1;
                char ch;
                do
                {
                    int index2;
                    index1 = (index2 = index1) + 1;
                    ch = text[index2];
                }
                while (index1 < text.Length && (int)ch != 58 && ((int)ch != 123 && (int)ch != 125));
                int num1 = 0;
                if ((int)ch == 125 && (int)text[index1 - 1] == 45)
                    num1 = 1;
                string text1 = text.Substring(startIndex1, index1 - startIndex1 - num1 - 1).Trim();
                //if ("" != text1)
                //    block.AddTex(text1);
                if (index1 != text.Length)
                {
                    int startIndex2 = 0;
                    string buffer = (string)null;
                    string unparsedText = (string)null;
                    switch (ch)
                    {
                        case ':':
                            startIndex2 = GetTagIndex(text, index1);
                            buffer = text.Substring(index1, startIndex2 - index1);
                            break;
                        case '{':
                            if (text.Substring(index1).StartsWith("1:"))
                            {
                                int startIndex3 = index1 <= 0 ? 0 : index1 - 1;
                                startIndex2 = startIndex3 + 1;
                                string str = text.Substring(startIndex2);
                                while (startIndex2 < text.Length && !str.StartsWith("{1:"))
                                    startIndex2 = GetContainIndex(text, startIndex2 + 1);
                                string text2 = text.Substring(startIndex3, startIndex2 - startIndex3);
                                //block.AddTex(text2);
                                break;
                            }
                            else
                            {
                                startIndex2 = GetContainIndex(text, index1);
                                buffer = text.Substring(index1, startIndex2 - 1 - index1);
                                int num2 = buffer.IndexOf("{1:");
                                if (num2 != -1)
                                {
                                    unparsedText = buffer.Substring(num2);
                                    buffer = buffer.Substring(0, num2);
                                    break;
                                }
                                else
                                    break;
                            }
                        case '}':
                            if (index1 != text.Length)
                            {
                                int length = text.Length;
                                break;
                            }
                            else
                                break;
                    }
                    if (buffer != null)
                    {
                        string[] swiftTag =  GetSwiftTag(buffer, unparsedText);
                        if (swiftTag[0] != null && swiftTag[1] != null)
                            block.Add(swiftTag[0], swiftTag[1]);
                    }
                    index1 = startIndex2;
                }
            }
            return block;
        }

        private static string Validate(string data)
        {
            switch (data)
            {
                case null:
                    return data;
                default:
                    if (data.Length != 0)
                    {
                        int length1 = data.Length;
                        int length2;
                        if ((int)data[length2 = length1 - 1] == 45)
                        {
                            if (length2 > 0 && (int)data[length2 += -1] == 10 && (length2 > 0 && (int)data[length2 += -1] != 13))
                                ++length2;
                            data = length2 <= 0 ? "" : data.Substring(0, length2);
                            goto case null;
                        }
                        else
                            goto case null;
                    }
                    else
                        goto case null;
            }
        }

        private static int GetContainIndex(string s, int start)
        {
            int num = 0;
            char ch;
            do
            {
                int index;
                start = (index = start) + 1;
                switch (ch = s[index])
                {
                    case '{':
                        ++num;
                        break;
                    case '}':
                        num += -1;
                        break;
                }
            }
            while (start < s.Length && (num >= 0 || num == 0 && (int)ch != 125));
            return start;
        }

        private static int GetTagIndex(string s, int start)
        {
            for (; start < s.Length; ++start)
            {
                char ch1 = s[start];
                if ((int)ch1 == 13 || (int)ch1 == 10)
                {
                    int num = start;
                    if (start + 1 == s.Length)
                        return start;
                    char ch2 = s[++start];
                    switch (ch2)
                    {
                        case '\n':
                        case '\r':
                            if (start == s.Length)
                                return start;
                            ch2 = s[++start];
                            break;
                    }
                    if ((int)ch2 == 123 || (int)ch2 == 125)
                    {
                        start = num;
                        return start;
                    }
                    else
                    {
                        if ((int)ch2 == 58 && start != s.Length)
                        {
                            switch (s[++start])
                            {
                                case '\r':
                                case '\n':
                                    break;
                                default:
                                    start = num;
                                    return start;
                            }
                        }
                        start = num;
                    }
                }
                else
                {
                    if ((int)ch1 == 45)
                    {
                        ch1 = start + 1 >= s.Length ? ' ' : s[start + 1];
                        if ((int)ch1 == 125)
                            return start;
                    }
                    if ((int)ch1 == 125)
                        return start;
                }
            }
            return start;
        }

        private static string[] GetSwiftTag(string buffer, string unparsedText)
        {
            string[] ret = new string[2];
            
            int length1 = buffer.IndexOf(':');
            string str1 = (string)null;
            string str2;
            if (length1 != -1)
            {
                str1 = buffer.Substring(0, length1);
                str2 = buffer.Substring(length1 + 1);
            }
            else
                str2 = buffer;
            if ((str1 == null || str1 == "") && (str2 == null || str2 == ""))
                return ret;
            int length2 = str2.Length;
            if (length2 > 0)
            {
                switch (str2[length2 - 1])
                {
                    case '\n':
                    case '\r':
                        length2 += -1;
                        break;
                }
            }
            if (length2 > 0)
            {
                switch (str2[length2 - 1])
                {
                    case '\n':
                    case '\r':
                        length2 += -1;
                        break;
                }
            }
            if (length2 != str2.Length)
                str2 = str2.Substring(0, length2);

            string[] swiftTag = new string[2];
            swiftTag[0] = str1;
            swiftTag[1] = str2;

            //if (unparsedText != null)
            //    swiftTag.UnparsedTexts = GetUnparsedTextList(unparsedText);
            return swiftTag;
        }
    }
}
